/**
 * 通用app网络请求
 * 基于 Promise 对象实现更简单的 request 使用方式，支持请求和响应拦截
 */
import {
	HTTP_REQUEST_URL,
	HEADER,
	TOKENNAME,
	HEADERPARAMS
} from '@/config/app';
import {
	toLogin,
	checkLogin
} from '../libs/login';
import store from '../store';
import { BACK_URL } from '@/config/cache';
import Cache from '../utils/cache';
import {
	getTerminal
} from "./util";

import { signatureGenerate } from './signature'
// import qs from 'qs'
import { encrypt, decrypt } from './encrypt';

let subscribers = [];
let isRefreshing = true;

function onAccessTokenFetched() {
	subscribers.forEach((callback) => {
		console.info("依次去执行缓存的接口 onAccessTokenFetched");
		console.table(callback);
		callback();
	})
	subscribers = [];
}

function addSubscriber(callback) {
	subscribers.push(callback);
	console.log('重新请求的队列', callback, subscribers)
}

function deleteUndefinedProperties(obj) {
	for (let key in obj) {
		if (obj.hasOwnProperty(key)) {
			if (typeof obj[key] === 'object' && obj[key] !== null) {
				deleteUndefinedProperties(obj[key]); // 递归调用，处理嵌套的对象
			} else if (obj[key] === undefined) {
				delete obj[key];
			}
		}
	}
}

const config = {
	// 请求的公共url
	baseUrl: HTTP_REQUEST_URL + "/",
	header: HEADER,
	tenantId: '1',
	data: {},
	method: "GET",
	dataType: "json",
	responseType: "text",
	success() {},
	fail() {},
	complete() {}
}

const interceptor = {
	request: null,
	response: null
}

function baseRequest(options, opt) {
	// console.table(options);
	if (!options) {
		options = {}
	}
	// 获取登录后存储在本地的token信息
	// let token = uni.getStorageSync('dawnToken')
	let requestType = options.url.split('/')
	let typeVal = requestType[requestType.length - 1]
	// if (typeVal !== 'userLogin' && typeVal !== 'register' && typeVal !== 'sendSms') {
	// 	// 判断筛选出以上三个页面不需要为请求头设置token，根据自己的项目情况而定
	// 	config.header.Authorization = token
	// } else {
	// 	delete config.header.Authorization
	// }

	options.apiUrl = options.url
	options.dataType = config.dataType
	options.url = config.baseUrl + options.url
	options.data = options.data || {}
	options.method = options.method || config.method
	config.header = options.header || config.header

	options.data.appType = 'WX'
	// #ifdef H5
	// options.data.appType = 'H5'
	// #endif
	let ui = location.pathname + location.search;
	let snRouter = uni.getStorageSync('snRouter');
	if(snRouter){
		ui = ui+'******snRouter='+snRouter;
	}
	if(Cache.get(BACK_URL)){
		ui = ui+'******'+BACK_URL+'='+Cache.get(BACK_URL);
	}
	options.data.ui = ui;

	if (opt && opt.sign) {
		// 获取请求头参数
		const { signature, timestamp, secret } = signatureGenerate(options)
		// 分别将签名、密钥、时间戳 至请求头
		if (signature) config.header['s'] = signature
		if (timestamp) config.header['t'] = timestamp
		if (secret) config.header['sc'] = secret
		// options.data = qs.stringify(options.data)
	}

	// console.table(opt);
	if (opt && !opt.noAuth && ui.indexOf('/hosp/login/wechat_login') === -1) {
		//登录过期自动登录
		if (!store.state.app.token && !checkLogin()) {
			toLogin();
			return Promise.reject({
				msg: '未登录'
			});
		}
	}

	deleteUndefinedProperties(options.data)

	// if (options.url.indexOf('app-api') >= 0) {
	// 	config.header['tenant-id'] = config.tenantId
	// }
	config.header['tenant-id'] = config.tenantId

	// 终端
	config.header['terminal'] = getTerminal();

	if (store.state.app.token) {
		// header[TOKENNAME] = store.state.app.token;
		config.header['Authorization'] = 'Bearer ' + store.state.app.token;
	}

	// console.table(config.header);
	// console.table(options);


	// 基于 Promise 的网络请求
	return new Promise((resolve, reject) => {
		if (!options.callback && options.loading) {
			// uni.showLoading({
			// 	title: '加载中...'
			// });
		}

		let _config = null
		let _this = this
		options.complete = (response) => {

			if (response.header['x-encrypted'] === 'true') {
				response.data.data = decrypt(response.data.data)
			}
			// console.log('callback', callback)
			if (options.callback) {
				// uni.hideLoading();
				return options.callback(response.data)
			};

			let statusCode = response.statusCode
			response.config = _config

			if (process.env.NODE_ENV === 'development') {
				if (statusCode === 200) {
					// console.log("【" + _config.requestId + "】 结果：" + JSON.stringify(response.data))
				}
			}

			if (interceptor.response) {
				let newResponse = interceptor.response(response)
				if (newResponse) {
					response = newResponse
				}
			}
			let {
				code,
				msg
			} = response.data

			// 请求返回400请求报文存在语法错误时reLaunch到登录页
			// console.info("request response");
			// console.table(response.data);
			if (response.data.code == 400) {
				// uni.hideLoading()
				// tool.msg(msg)
				// setTimeout(() => {
				//   uni.redirectTo({
				//     url: '/main/index/index'
				//   })
				// }, 1000)
				// reject(response.data)
				resolve(response.data)
			} else if (code == 0) {
				// tool.msg(msg)
				// uni.hideLoading()
				resolve(response.data)
			} else if (code == 401) {
				console.log('触发了一次401', options.url);
				options.url = options.apiUrl;
				options.callback = resolve;
				addSubscriber(() => {
					baseRequest(options, opt);
				});

				console.log('isRefreshing----', isRefreshing)
				if (isRefreshing) {
					refreshToken().then(res => {
						// 依次去执行缓存的接口
						console.info("依次去执行缓存的接口");
						onAccessTokenFetched();
						isRefreshing = true;
					}).catch(err => {
						toLogin();
					})
				}
				isRefreshing = false;
				console.log('isRefreshing:', isRefreshing)
			} else {
				// uni.hideLoading()
				resolve(response.data)
			}
		}

		_config = Object.assign({}, config, options)
		_config.requestId = new Date().getTime()

		if (_config.method?.toUpperCase() === 'POST' && _config.dataType?.toUpperCase() === 'JSON') {
			_config.header['x-encrypted'] = 'true'
			_config.data = encrypt(_config.data)
		} else {
			_config.header['x-encrypted'] = 'false'
		}

		if (interceptor.request) {
			interceptor.request(_config)
		}

		uni.request(_config);
	});
}


// 刷新token
const refreshToken = () => {
	console.info("刷新token refreshToken:" + store.state.app.refreshToken);
	if (!store.state.app.refreshToken) {
		toLogin();
		return;
	}
	return new Promise((resolve, reject) => {
		uni.request({
			url: config.baseUrl + "member/auth/refresh-token?refreshToken=" + store.state
				.app.refreshToken,
			data: {},
			method: 'POST',
			header: {
				'content-type': 'application/json',
				'Tenant-Id': config.tenantId,
				'Terminal': getTerminal()
			},
			success(res) {
				console.log('重新登陆成功返回');
				console.table(res);
				let r = res.data;
				if (r.code == 0) {
					store.commit("LOGIN", {
						'token': r.data.accessToken
					});
					// 设置刷新令牌
					store.commit('REFRESH_LOGIN', {
						refreshToken: r.data.refreshToken
					});
					resolve(r); //通过Promise的 resolve(),把返回的结果暴露出去 ， 可以不用
				} else {
					toLogin();
				}
			}
		})
	})
}


const request = {};

['options', 'get', 'post', 'put', 'head', 'delete', 'trace', 'connect'].forEach((method) => {
	request[method] = (api, data, opt, params) => baseRequest({
		url: api,
		data: data,
		method: method,
		params: params
	}, opt || {})
});



export default request;